home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_se / reverse_assignment.e < prev    next >
Text File  |  2000-03-25  |  8KB  |  257 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class REVERSE_ASSIGNMENT
  17.    --
  18.    -- For instructions like :
  19.    --                          foo ?= bar;
  20.    --                          foo ?= bar + 1;
  21.    --
  22.  
  23. inherit INSTRUCTION;
  24.  
  25. creation make
  26.  
  27. feature
  28.  
  29.    left_side: EXPRESSION;
  30.  
  31.    right_side: EXPRESSION;
  32.  
  33.    end_mark_comment: BOOLEAN is false;
  34.  
  35.    use_current: BOOLEAN is
  36.       do
  37.          if left_side.use_current then
  38.             Result := true;
  39.          else
  40.             Result := right_side.use_current;
  41.          end;
  42.       end;
  43.  
  44.    stupid_switch(r: ARRAY[RUN_CLASS]): BOOLEAN is
  45.       do
  46.          if small_eiffel.stupid_switch(left_side.result_type,r) then
  47.             if small_eiffel.stupid_switch(right_side.result_type,r) then
  48.                if left_side.stupid_switch(r) then
  49.                   if right_side.stupid_switch(r) then
  50.                      Result := true;
  51.                   end;
  52.                end;
  53.             end;
  54.          end;
  55.       end;
  56.  
  57.    afd_check is
  58.       do
  59.          right_side.afd_check;
  60.       end;
  61.  
  62.    collect_c_tmp is
  63.       do
  64.          right_side.collect_c_tmp;
  65.       end;
  66.  
  67.    compile_to_c is
  68.       local
  69.          run: ARRAY[RUN_CLASS];
  70.          i: INTEGER;
  71.       do
  72.          cpp.se_trace_ins(start_position);
  73.          if right_type.run_type.is_expanded then
  74.             eh.add_position(start_position);
  75.             fatal_error("Right-hand side expanded Not Yet Implemented.");
  76.          end;
  77.          run := left_type.run_class.running;
  78.          if run = Void then
  79.             if not right_side.can_be_dropped then
  80.                right_side.compile_to_c;
  81.                cpp.put_string(fz_00);
  82.             end;
  83.             left_side.compile_to_c;
  84.             cpp.put_string(fz_30);
  85.          elseif right_side.is_current then
  86.             if run.fast_has(right_side.result_type.run_class) then
  87.                left_side.compile_to_c;
  88.                cpp.put_string("=((void*)");
  89.                right_side.compile_to_c;
  90.                cpp.put_string(fz_14);
  91.             else
  92.                left_side.compile_to_c;
  93.                cpp.put_string(fz_30);
  94.             end;
  95.          else
  96.             left_side.compile_to_c;
  97.             cpp.put_character('=');
  98.             if right_side.is_current then
  99.                cpp.put_string(fz_cast_t0_star);
  100.             end;
  101.             right_side.compile_to_c;
  102.             cpp.put_string(";%Nif(NULL!=(");
  103.             left_side.compile_to_c;
  104.             cpp.put_string(")){%Nswitch(((T0*)");
  105.             left_side.compile_to_c;
  106.             cpp.put_string(")->");
  107.             cpp.put_string("id){%N");
  108.             from
  109.                i := run.lower;
  110.             until
  111.                i > run.upper
  112.             loop
  113.                cpp.put_string("case ");
  114.                cpp.put_integer(run.item(i).id);
  115.                cpp.put_character(':');
  116.                i := i + 1;
  117.             end;
  118.             cpp.put_string("%Nbreak;%Ndefault:%N");
  119.             left_side.compile_to_c;
  120.             cpp.put_string("=NULL;%N}%N}");
  121.          end;
  122.       end;
  123.  
  124.    compile_to_jvm is
  125.       local
  126.          run: ARRAY[RUN_CLASS];
  127.          rc: RUN_CLASS;
  128.          point1, i: INTEGER;
  129.          ca: like code_attribute;
  130.       do
  131.          ca := code_attribute;
  132.          if right_type.run_type.is_expanded then
  133.             eh.add_position(start_position);
  134.             fatal_error("Right-hand side expanded Not Yet Implemented.");
  135.          end;
  136.          run := left_type.run_class.running;
  137.          if run = Void or else run.is_empty then
  138.             right_side.compile_to_jvm;
  139.             ca.opcode_pop;
  140.             ca.opcode_aconst_null;
  141.             left_side.jvm_assign;
  142.          else
  143.             right_side.compile_to_jvm;
  144.             ca.opcode_dup;
  145.             point1 := ca.opcode_ifnull;
  146.             from
  147.                ca.branches.clear;
  148.                i := run.upper;
  149.             until
  150.                i = 0
  151.             loop
  152.                ca.opcode_dup;
  153.                rc := run.item(i);
  154.                rc.opcode_instanceof;
  155.                ca.branches.add_last(ca.opcode_ifne);
  156.                i := i - 1;
  157.             end;
  158.             ca.opcode_pop;
  159.             ca.opcode_aconst_null;
  160.             ca.resolve_u2_branch(point1);
  161.             ca.resolve_branches;
  162.             left_side.jvm_assign;
  163.          end;
  164.       end;
  165.  
  166.    is_pre_computable: BOOLEAN is false;
  167.  
  168.    start_position: POSITION is
  169.       do
  170.          Result := left_side.start_position;
  171.       end;
  172.  
  173.    to_runnable(ct: TYPE): like Current is
  174.       local
  175.          e: EXPRESSION;
  176.       do
  177.          if current_type = Void then
  178.             current_type := ct;
  179.             e := left_side.to_runnable(ct);
  180.             if e = Void then
  181.                error(left_side.start_position,fz_blhsoa);
  182.             else
  183.                left_side := e;
  184.             end;
  185.             if nb_errors = 0  then
  186.                e := right_side.to_runnable(ct);
  187.                if e = Void then
  188.                   error(right_side.start_position,fz_brhsoa);
  189.                else
  190.                   right_side := e;
  191.                end;
  192.             end;
  193.             if nb_errors = 0 and then
  194.                right_type.run_type.is_a(left_type.run_type) then
  195.                if not right_side.is_current and then
  196.                   not left_type.is_like_current
  197.                 then
  198.                   eh.add_type(right_type," is a ");
  199.                   eh.add_type(left_type,". Simple assignment is allowed");
  200.                   warning(start_position," (%"?=%" is not necessary).");
  201.                end;
  202.             end;
  203.             eh.cancel;
  204.             if not left_type.run_type.is_reference then
  205.                eh.add_type(left_type.run_type," is not a reference Type.");
  206.                error(start_position," Invalid reverse assignment (VJRV).");
  207.             end;
  208.             if nb_errors = 0 then
  209.                Result := Current;
  210.             end;
  211.          else
  212.             !!Result.make(left_side,right_side);
  213.             Result := Result.to_runnable(ct);
  214.          end;
  215.       end;
  216.  
  217.    right_type: TYPE is
  218.       do
  219.          Result := right_side.result_type;
  220.       ensure
  221.          Result /= Void
  222.       end;
  223.  
  224.    left_type: TYPE is
  225.       do
  226.          Result := left_side.result_type;
  227.       ensure
  228.          Result /= Void
  229.       end;
  230.  
  231.    pretty_print is
  232.       do
  233.          pretty_print_assignment(left_side,"?=",right_side);
  234.       end;
  235.  
  236. feature {NONE}
  237.  
  238.    current_type: TYPE;
  239.  
  240.    make(ls: like left_side; rs: like right_side) is
  241.       require
  242.          ls /= Void;
  243.          rs /= Void
  244.       do
  245.          left_side := ls;
  246.          right_side := rs;
  247.       end;
  248.  
  249. invariant
  250.  
  251.    left_side.is_writable;
  252.  
  253.    right_side /= Void;
  254.  
  255. end -- REVERSE_ASSIGNMENT
  256.  
  257.